package com.wootion.cims.module.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wootion.cims.dao.PersonDao;
import com.wootion.cims.dao.ResidenceDao;
import com.wootion.cims.dao.SysCommunityDao;
import com.wootion.cims.dao.SysLogDao;
import com.wootion.cims.general.utils.GetIp;
import com.wootion.cims.module.communitypersonal.model.Person;
import com.wootion.cims.module.communityresidence.residencelist.model.Residence;
import com.wootion.cims.dao.*;
import com.wootion.cims.general.utils.GetIp;
import com.wootion.cims.module.communitymerchant.model.Shop;
import com.wootion.cims.module.communityresidence.residencelist.model.Residence;
import com.wootion.cims.module.systemsetting.community.model.SysCommunity;
import com.wootion.cims.module.systemsetting.dictionary.model.LogAnotion;
import com.wootion.cims.module.systemsetting.dictionary.model.SysDictionary;
import com.wootion.cims.module.systemsetting.log.model.SysLog;
import com.wootion.cims.module.systemsetting.polt.model.SysPlot;
import com.wootion.cims.module.systemsetting.role.model.SysRole;
import com.wootion.cims.module.systemsetting.user.model.User;
import com.wootion.cims.response.ResponseResult;
import com.wootion.cims.response.ResultCode;
import com.wootion.cims.shiro.utils.ShiroUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.*;

@Aspect
@Component
@Slf4j
public class MyAop {
    @Autowired(required = false)
    SysCommunityDao sysCommunityDao;

    @Autowired(required = false)
    SysPlotDao sysPlotDao;

    @Autowired(required = false)
    SysDictionaryDao sysDictionaryDao;

    @Autowired(required = false)
    SysRoleDao sysRoleDao;

    @Autowired(required = false)
    UserDao userDao;

    @Autowired(required = false)
    ShopDao shopDao;

    @Autowired(required = false)
    ResidenceDao residenceDao;

    @Autowired(required = false)
    SysLogDao sysLogDao;

    @Autowired(required = false)
    PersonDao personDao;


    @Pointcut("@annotation(com.wootion.cims.module.systemsetting.dictionary.model.LogAnotion)")
    public void systemsetting() {
    }

    @Around(value = "systemsetting()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("==============开始记录日志==============\n");
        User user = (User) ShiroUtils.getSubject().getPrincipal();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        LogAnotion annotation = methodSignature.getMethod().getAnnotation(LogAnotion.class);
        SysLog sysLog = new SysLog();
        sysLog.setOperator(user.getUsername());//获取操作人
        sysLog.setIp(GetIp.getIpAddr(request));//获取操作人
        sysLog.setCreateTime(new Date());//获取操作的事件
        sysLog.setIncident(annotation.incident());//获取操作类别
        String value = annotation.value();
        String prefixContent = annotation.prefixContent();//获取内容前缀

        StringBuilder stringBuilder = new StringBuilder(prefixContent);
        if(!annotation.incident().equals("个人信息")){
            stringBuilder.append(":");
        }
        if (StringUtils.hasText(value)) {
            if ("0".equals(value)) {
                sysLog.setValue("系统日志");
            } else {
                sysLog.setValue("业务日志");
            }
        }

        String type = annotation.type();
        if ("修改".equals(type)) {
            Object[] args1 = joinPoint.getArgs();
            if (!Objects.isNull(args1)) {
                for (Object o : args1) {
                    if(o instanceof ShiroHttpServletRequest){
                        break;
                    }
                    String jsonString = JSONObject.toJSONString(o);
                    JSONObject jsonObject = JSONObject.parseObject(jsonString);
                    String name = (String) jsonObject.get("name");
                    if(StringUtils.hasText(name)){
                        sysLog.setContent(stringBuilder.append(name).toString());
                    }else {
                        String username = (String) jsonObject.get("username");
                        sysLog.setContent(stringBuilder.append(username).toString());
                    }

                }
            }
            for (Object o : args1) {
                if(o instanceof ShiroHttpServletRequest){
                    break;
                }
                Class<?> aClass = o.getClass();
                if (updateCovt3(annotation.incident())){
                    Class<?> aClass1 = updateCovt2(annotation.incident());
                    aClass=aClass1;
                }

                Field[] declaredFields = aClass.getDeclaredFields();

                String jsonString = JSONObject.toJSONString(o);
                JSONObject jsonObject = JSONObject.parseObject(jsonString);

                String id = (String) jsonObject.get("id");
                //这里需要判断
                JSONObject jsonObject1 = updateCovt(annotation.incident(), id);
                StringBuilder stringBuilder1 = new StringBuilder();
                for (Field declaredField : declaredFields) {
                    String name = declaredField.getName();
                    Object string1 = jsonObject1.get(name);//原本的
                    Object string = jsonObject.get(name);//修改后的
                    if (Objects.isNull(string) || Objects.isNull(string1)){
                        continue;
                    }
                    ApiModelProperty annotation1 = declaredField.getAnnotation(ApiModelProperty.class);
                    String value1 = annotation1.value();//获取注解的注释
                    if (!string.equals(string1)){
                        stringBuilder1.append(value1+"被修改,修改前:"+string1+",修改后:"+string+"。");
                    }
                }
                sysLog.setDetails(stringBuilder1.toString());
            }
        }

        //执行方法
        ResponseResult result = (ResponseResult) joinPoint.proceed();
        if (result.getCode().equals(ResultCode.NORMAL.getCode())) {
            sysLog.setResult("成功");
        } else {
            sysLog.setResult("失败");
        }

        Object[] args = joinPoint.getArgs();
        sysLog.setType(type);
        if ("新增".equals(type)) {
            if (!Objects.isNull(args)) {
                for (Object o : args) {
                    if(o instanceof ShiroHttpServletRequest){
                        break;
                    }
                    String jsonString = JSONObject.toJSONString(o);
                    JSONObject jsonObject = JSONObject.parseObject(jsonString);
                    String name = (String) jsonObject.get("name");
                    if(StringUtils.hasText(name)){
                        if(annotation.incident().equals("个人信息")){
                            if(StringUtils.hasText(name)){
                                stringBuilder.append(name);
                            }
                            String idNumber = jsonObject.getString("idNumber");
                            if(StringUtils.hasText(idNumber)){
                                stringBuilder.append("(").append(idNumber).append(")");
                                sysLog.setContent(stringBuilder.toString());
                            }
                        }else {
                            sysLog.setContent(stringBuilder.append(name).toString());
                        }
                    }else {
                        String username = (String) jsonObject.get("username");
                        sysLog.setContent(stringBuilder.append(username).toString());
                    }

                }
            }
        } else if ("删除".equals(type)) {
            if (!Objects.isNull(args)) {
                for (Object o : args) {
                    if(o instanceof ShiroHttpServletRequest){
                        break;
                    }
                    String jsonString = JSONObject.toJSONString(o);
                    JSONObject jsonObject = JSONObject.parseObject(jsonString);
                    String id = (String) jsonObject.get("id");
                    String incident = annotation.incident();
                    String msg = queryId(incident, id);
                    sysLog.setContent(stringBuilder.append(msg).toString());
                }
            }
        } else if ("导出".equals(type)) {
            sysLog.setContent("执行导出操作");
        }else if ("批量删除".equals(type)) {
            Object[] args1 = joinPoint.getArgs();
            if (!Objects.isNull(args1)) {
                for (Object o : args1) {
                    if(o instanceof ShiroHttpServletRequest){
                        break;
                    }
                    String jsonString = JSONObject.toJSONString(o);
                    JSONObject jsonObject = JSONObject.parseObject(jsonString);
                    JSONArray ids1 = jsonObject.getJSONArray("ids");
                    List<String> list2 = ids1.toJavaList(String.class);
                    int size = list2.size();
                    stringBuilder.append("共"+size+"条");
                    String deleteUsers = getDeleteUsers(annotation.incident(), list2);
                    sysLog.setDetails(deleteUsers);
                }
            }
            sysLog.setContent(stringBuilder.toString());
        }

        int rows = sysLogDao.insert(sysLog);
        if (rows > 0) {
            log.info("日志记录成功");
        } else {
            log.error("日志记录失败");
        }
        return result;
    }

    public String queryId(String incident,String id){
        switch (incident){
            case "社区信息":
                SysCommunity sysCommunity = sysCommunityDao.selectById(id);
                return sysCommunity.getName();
            case "小区信息":
                SysPlot sysPlot = sysPlotDao.selectById(id);
                return sysPlot.getName();
            case "字典信息":
                SysDictionary sysDictionary = sysDictionaryDao.selectById(id);
                return sysDictionary.getName();
            case "角色信息":
                SysRole sysRole = sysRoleDao.selectById(id);
                return sysRole.getName();
            case "账号信息":
                User user = userDao.selectById(id);
                return user.getUsername();
            case "门店信息":
                Shop shop = shopDao.selectById(id);
                return shop.getName();
            case "住宅信息":
                StringBuilder stringBuilder = new StringBuilder();
                Residence residence = residenceDao.selectById(id);
                String communityId = residence.getCommunityId();
                String communityName = sysCommunityDao.selectById(communityId).getName();
                stringBuilder.append(communityName);
                String plotId = residence.getPlotId();
                String plotName = sysPlotDao.selectById(plotId).getName();
                stringBuilder.append(plotName);
                String category = residence.getCategory();//楼房  平房/别墅
                stringBuilder.append(category);
                String address = residence.getAddress();//5栋/3单元
                stringBuilder.append(address);
                String houseNumber = residence.getHouseNumber();//门牌号
                stringBuilder.append(houseNumber);
                return stringBuilder.toString();
        }
        return null;
    }

    public JSONObject updateCovt(String incident,String id){
        switch (incident){
            case "社区信息":
                SysCommunity sysCommunity = sysCommunityDao.selectById(id);
                return JSONObject.parseObject(JSONObject.toJSONString(sysCommunity));
            case "小区信息":
                SysPlot sysPlot = sysPlotDao.selectById(id);
                return JSONObject.parseObject(JSONObject.toJSONString(sysPlot));
            case "字典信息":
                SysDictionary sysDictionary = sysDictionaryDao.selectById(id);
                return JSONObject.parseObject(JSONObject.toJSONString(sysDictionary));
            case "角色信息":
                SysRole sysRole = sysRoleDao.selectById(id);
                return JSONObject.parseObject(JSONObject.toJSONString(sysRole));
            case "账号信息":
                User user = userDao.selectById(id);
                return JSONObject.parseObject(JSONObject.toJSONString(user));
            case "门店信息":
                Shop shop = shopDao.selectById(id);
                return JSONObject.parseObject(JSONObject.toJSONString(shop));
        }
        return null;
    }

    public Class<?>  updateCovt2(String incident){
        switch (incident){
            case "字典信息":
                return SysDictionary.class;
            case "角色信息":
                return SysRole.class;
            case "账号信息":
                return User.class;
            case "门店信息":
                return Shop.class;
        }
        return null;
    }

    public boolean  updateCovt3(String incident){
        switch (incident){
            case "字典信息":
                return true;
            case "角色信息":
                return true;
            case "账号信息":
                return true;
            case "门店信息":
                return true;
        }
        return false;
    }

    private String getDeleteUsers (String type,List<String> list2){

        switch (type){
            case "个人信息" :{
                StringBuilder stringBuilder = new StringBuilder("姓名:");
                for (String id : list2) {
                    Person person = personDao.selectById(id);
                    if (Optional.ofNullable(person).isPresent()){
                        stringBuilder.append(person.getName()+"("+person.getIdNumber()+"),");
                    }
                }
                String string = stringBuilder.toString();
                String substring = string.substring(0, string.length() - 1);
                return substring;
            }
            case "住宅信息" :{
                StringBuilder stringBuilder = new StringBuilder("地址:");
                for (String id : list2) {
                    Residence residence = residenceDao.selectById(id);
                    String communityId = residence.getCommunityId();
                    String communityName = sysCommunityDao.selectById(communityId).getName();
                    stringBuilder.append(communityName);
                    String plotId = residence.getPlotId();
                    String plotName = sysPlotDao.selectById(plotId).getName();
                    stringBuilder.append(plotName);
                    String category = residence.getCategory();//楼房  平房/别墅
                    stringBuilder.append(category);
                    String address = residence.getAddress();//5栋/3单元
                    stringBuilder.append(address);
                    String houseNumber = residence.getHouseNumber();//门牌号
                    stringBuilder.append(houseNumber+",");
                }
                String string = stringBuilder.toString();
                String substring = string.substring(0, string.length() - 1);
                return substring;
            }
        }
        return null;
    }
}